package query.io.converters;

import java.util.ArrayList;
import java.util.List;

import query.model.UserQuery;

import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.mapper.Mapper;

/**
 * A specific {@link AbstractReflectionConverter} 
 */
public class UserQueryReflexionConverter extends AbstractReflectionConverter
{
  /** The Constant TEXT. */
  private static final String TEXT = "text";
  
  /** The Constant QUERY. */
  private static final String QUERY = "query";

  /**
   * Instantiates a new user query reflexion converter.
   *
   * @param mapper the mapper
   * @param reflectionProvider the reflection provider
   */
  public UserQueryReflexionConverter(Mapper mapper, ReflectionProvider reflectionProvider)
  {
    super(mapper, reflectionProvider);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context)
  {
    List<UserQuery> queries = new ArrayList<>();

    while (reader.hasMoreChildren())
    {
      reader.moveDown();
      String nodeName = reader.getNodeName();
      switch (nodeName)
      {
      case QUERY :
        queries.add(unmarshallQuery(reader, reader.getAttribute("id")));
        break;
      default :
        break;
      }
      reader.moveUp();
    }
    
    return queries;
  }

  /**
   * Unmarshall a query.
   *
   * @param reader the reader
   * @param queryName the query name
   * @return the user query
   */
  private UserQuery unmarshallQuery(HierarchicalStreamReader reader, String queryName)
  {
    UserQuery query = null;
    while(reader.hasMoreChildren())
    {
      reader.moveDown();
      String nodeName = reader.getNodeName();
      switch(nodeName)
      {
        case TEXT :
          query = new UserQuery(queryName.replace("q", ""), reader.getValue());
          break;
      }
      reader.moveUp();
    }
    return query;
  }

  /**
   * {@inheritDoc}
   */
  @SuppressWarnings("rawtypes")
  @Override
  public boolean canConvert(Class type)
  {
    return type == UserQuery.class;
  }

}
